package com.cf.game.cowboy;

import com.cf.game.Player;
import com.cf.game.cowboy.handler.LotteryStrategy;
import com.cf.game.cowboy.handler.model.GameResult;
import com.cf.game.cowboy.msg.CowGameInfoResponse;
import com.cf.game.cowboy.msg.CowGameResultResponse;
import com.cf.game.service.constants.EnumH5CowBoyGameState;
import com.cf.game.service.pojo.H5GameInstance;
import com.cf.game.service.schedule.CircleCapableTimingWheel;
import com.cf.game.service.schedule.ExpirationListener;
import com.cf.game.service.service.h5game.H5GameInstanceService;
import com.cf.game.service.thread.ThreadPool;
import com.cf.game.service.util.BeanFactoryUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * cf-game-CowBoyTimingWheel
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/3/27 13:39
 */
@Slf4j
public class CowBoyTimingWheel {

    private static int tickDuration = 1000;

    private static int timeoutInMillis = 30 * 1000;

    public static CircleCapableTimingWheel<StateExpire> timingWheel;

    static {
        timingWheel = new CircleCapableTimingWheel<>(tickDuration, timeoutInMillis / tickDuration, TimeUnit.MILLISECONDS);
        timingWheel.addExpirationListener(new ExpirationListener<StateExpire>() {
            @Override
            public void expired(StateExpire expiredObject) {
                if (expiredObject.getFrom().equals(EnumH5CowBoyGameState.STAKE) && expiredObject.getTo().equals(EnumH5CowBoyGameState.LOTTERY)) {
                    log.info("开始开奖。。。。。");
                    expiredObject.getTargetGame().updateState(EnumH5CowBoyGameState.LOTTERY);
                    ThreadPool.getInstance().execute(new Runnable() {
                        @Override
                        public void run() {
                            //生成开奖结果
                            try {
                                GameResult lotteryResult = BeanFactoryUtil.getBean(LotteryStrategy.class).getLotteryResult(expiredObject.getTargetGame());
                                expiredObject.getTargetGame().gameStateDetail.setGameResult(lotteryResult);
                                Integer winIndex = lotteryResult.getWinIndex();
                                for (int start = 0; start < winIndex; start++) {
                                    CowGameResultResponse resultResponse = new CowGameResultResponse(false, false, 0d, start % 2);
                                    expiredObject.getTargetGame().broadcast(resultResponse);
                                    try {
                                        Thread.sleep(4 * 1000L);
                                    } catch (InterruptedException e) {
                                        log.error("开奖线程被提前唤醒！。。。", e);
                                    }
                                }

                                Collection<Player> players = expiredObject.getTargetGame().players.values();

                                //开奖结果下发客户端
                                for (Player player : players) {
                                    Map<Integer, Double> winUsers = lotteryResult.getWinUsers();
                                    Double winMoney = winUsers.get(player.getUserInfo().getId());
                                    CowGameResultResponse resultResponse = new CowGameResultResponse(true, winMoney != null, winMoney == null ? 0 : winMoney, winIndex % 2);
                                    player.unicast(resultResponse);
                                }
                            } catch (Exception e) {
                                log.error("开奖错误！", e);
                            } finally {
                                //添加定时任务,触发,开始新的一局
                                timingWheel.add(new StateExpire(expiredObject.getTargetGame(), EnumH5CowBoyGameState.LOTTERY, EnumH5CowBoyGameState.STAKE), 5 * 1000L);
                            }
                        }
                    });
                } else {

                    ThreadPool.getInstance().execute(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //重新开始
                                log.info("开始新一轮游戏。。。。。");
                                //生成新的游戏实例
                                H5GameInstance gameInstance = BeanFactoryUtil.getBean(H5GameInstanceService.class).createNewInstance(expiredObject.getTargetGame().game.getId());
                                //(1)重置状态
                                expiredObject.getTargetGame().refreshAndStart(gameInstance);
                                expiredObject.getTargetGame().updateState(EnumH5CowBoyGameState.STAKE);
                                //(2)下发游戏开始信息
                                CowGameInfoResponse cowGameInfoResponse = expiredObject.getTargetGame().gameStateDetail.toCowQueryGameInfoResponse(-1);
                                cowGameInfoResponse.setCanPlay(true);
                                expiredObject.getTargetGame().broadcast(cowGameInfoResponse);
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                //(3)添加定时任务,触发
                                timingWheel.add(new StateExpire(expiredObject.getTargetGame(), EnumH5CowBoyGameState.STAKE, EnumH5CowBoyGameState.LOTTERY), CowBoyGame.Stake_Time);
                            }
                        }
                    });
                }
            }
        });
        timingWheel.start();
    }


}
